#include "pcanreceiver.h"
#include <QElapsedTimer>
#include <QDebug>

#include "PCANBasic.h"

PCANReceiver::PCANReceiver(QObject *parent)
    : QObject(parent), m_handle(PCAN_USBBUS1), m_connected(false), m_running(false)
{
    // 将当前对象移动到接收线程
    moveToThread(&m_receiveThread);
    
    // 连接线程启动信号到接收循环
    connect(&m_receiveThread, &QThread::started, this, &PCANReceiver::receiveLoop);
}

PCANReceiver::~PCANReceiver()
{
    //stopReceiving();
    disconnectDevice();
    m_receiveThread.wait();
}

//设备断开核心实现
void PCANReceiver::disconnectDevice()
{
    // 加锁：保护m_connected、m_running等共享状态（避免多线程冲突）
    QMutexLocker locker(&m_mutex);

    // 1. 如果设备未连接，直接返回（避免重复操作）
    if (!m_connected) {
        return;
    }

    // 2. 停止接收循环（设置m_running=false，让receiveLoop退出）
    m_running = false;
    // 等待接收线程结束（最多等1秒，避免阻塞主线程）
    if (m_receiveThread.isRunning()) {
        qInfo() << "等待接收线程停止...";
        if (!m_receiveThread.wait(3000)) {  // 1000ms超时
            m_receiveThread.terminate();    // 超时后强制终止（万不得已的兜底）
            m_receiveThread.wait();
            emit errorOccurred("PCAN接收线程超时，已强制终止");
        } else {
            qInfo() << "PCAN接收线程已正常停止";
        }
    }

    // 第二步：确认线程状态（双重保险）
    if (m_receiveThread.isRunning()) {
        qCritical() << "线程未停止，无法安全释放设备！";
        return; // 线程未停，放弃释放，避免冲突
    }

    // 3. 关闭PCAN设备连接（调用PCAN-Basic库接口）
    TPCANStatus status = CAN_Uninitialize(m_handle);
    qInfo() << "PCAN设备断开状态：" << status << "（0=成功，32=已被占用）";
    if (status == PCAN_ERROR_OK) {
        m_connected = false;  // 重置连接状态
        emit connectionStatusChanged(false);  // 发射“断开”状态信号
        emit errorOccurred("PCAN设备已成功断开连接");
        qInfo() << "PCAN设备断开成功";
    } else {
        // 断开失败时，仍重置状态（避免后续误判），并发射错误信号
        m_connected = false;
        emit connectionStatusChanged(false);
        emit errorOccurred("PCAN设备断开失败：" + getErrorString(status));
        qWarning() << "PCAN设备断开失败：" << getErrorString(status);
    }
}

bool PCANReceiver::init(const QString& configPath, TPCANHandle handle, int bitrate)
{
    qInfo() << "初始化PCAN设备 Handle:" << handle << "波特率:"<< bitrate;
    QMutexLocker locker(&m_mutex);
    
    // 加载协议配置
    if (!m_protManager.loadConfig(configPath)) {
        emit errorOccurred("加载配置文件失败: " + configPath);
        return false;
    }
    
    // 关闭已打开的设备
    if (m_connected) {
        CAN_Uninitialize(m_handle);
        m_connected = false;
    }

    // 关键：强制重置设备（清除驱动残留状态）
    TPCANStatus resetStatus = CAN_Reset(handle);  // 新增：重置设备

    // 关键：添加延迟，等待驱动刷新状态
    qInfo() << "刷新驱动状态...";
    QThread::msleep(100); // 500毫秒延迟

    // 保存设备句柄
    m_handle = handle;

    // 初始化前，先检查设备是否已被占用
    TPCANStatus preCheck = CAN_GetStatus(m_handle);
    if (preCheck == PCAN_ERROR_HWINUSE) {
        emit errorOccurred("初始化后设备状态异常: " + getErrorString(preCheck));
        CAN_Uninitialize(m_handle); // 立即释放异常设备
        m_connected = false;
        return false;
    }
    
    // 初始化PCAN设备
    TPCANStatus status = CAN_Initialize(m_handle, bitrate, 0, 0, 0);
    if (status != PCAN_ERROR_OK) {
        emit errorOccurred("设备初始化失败: " + getErrorString(status));
        return false;
    }

//    if( !setupCanFilter() ){
//        emit errorOccurred("滤波设置失败，关闭设备");
//        CAN_Uninitialize(m_handle);
//        return false;
//    }

    // 新增：初始化后设置共享模式
//    TPCANParameter param = PCAN_MODE; // 模式参数
//    DWORD paramValue = PCAN_MODE_SHARED; // 共享模式值
//    status = CAN_SetValue(m_handle, param, &paramValue, sizeof(paramValue));
//    if (status != PCAN_ERROR_OK) {
//        emit errorOccurred("设置共享模式失败: " + getErrorString(status));
//        CAN_Uninitialize(m_handle);
//        m_connected = false;
//        return false;
//    }

    // 新增：初始化后验证设备是否真正可用
    TPCANStatus postStatus = CAN_GetStatus(m_handle);
    if (postStatus != PCAN_ERROR_OK) {
        emit errorOccurred("初始化后设备不可用: " + getErrorString(postStatus));
        CAN_Uninitialize(m_handle);
        m_connected = false;
        return false;
    }
    
    m_connected = true;
    emit connectionStatusChanged(true);
    emit errorOccurred("PCAN设备初始化成功");
    return true;
}

// 滤波设置实现
bool PCANReceiver::setupCanFilter()
{
    QMutexLocker locker(&m_mutex); // 确保线程安全（与init函数共享互斥锁）
    TPCANStatus status;
    DWORD paramValue; // 存储滤波参数值
    // 旧版PCAN库滤波参数类型（数值常量，兼容无宏定义场景）
    const DWORD PCAN_PARAM_FILTER_OPERATION = 0x00000002; // 滤波模式（掩码/列表）
    const DWORD PCAN_PARAM_FILTER_CLEAR      = 0x00000003; // 清空滤波列表
    const DWORD PCAN_PARAM_FILTER_ADD        = 0x00000004; // 向列表添加ID

    // --------------------------
    // 1. 启用列表滤波模式（仅接收指定ID，不接收其他ID）
    // --------------------------
    TPCANParameter filterModeParam = static_cast<TPCANParameter>(PCAN_PARAM_FILTER_OPERATION);
    paramValue = 1; // 1=列表滤波（精准匹配指定ID），0=掩码滤波（范围匹配）
    status = CAN_SetValue(m_handle, filterModeParam, &paramValue, sizeof(paramValue));
    if (status != PCAN_ERROR_OK) {
       qWarning() << "设置列表滤波模式失败：" << getErrorString(status);
       return false;
    }
    qInfo() << "已启用列表滤波模式（仅接收指定ID）";

    // --------------------------
    // 2. 清空原有滤波规则（避免旧ID残留导致接收无关数据）
    // --------------------------
    TPCANParameter clearFilterParam = static_cast<TPCANParameter>(PCAN_PARAM_FILTER_CLEAR);
    paramValue = 0; // 清空操作固定传0（旧版库触发清空的约定）
    status = CAN_SetValue(m_handle, clearFilterParam, &paramValue, sizeof(paramValue));
    if (status != PCAN_ERROR_OK) {
       qWarning() << "清空原有滤波规则失败：" << getErrorString(status);
       return false;
    }
    qInfo() << "已清空原有滤波规则（避免旧ID干扰）";

    // --------------------------
    // 3. 定义目标ID：仅保留 0x41, 0x412, 0x43, 0x44, 0x45, 0x46（均为11位标准帧，0~0x7FF内）
    // --------------------------
    QList<DWORD> targetIds = {0x41, 0x412, 0x43, 0x44, 0x45, 0x46}; // 核心修改：替换为目标3个ID
    // 验证ID合法性（确保是11位标准帧，防止误加非法ID）
    foreach (DWORD id, targetIds) {
       if (id > 0x7FF) { // 11位标准帧最大ID为0x7FF（2047）
           qWarning() << "ID 0x" << QString::number(id, 16).toUpper()
                      << "非法（超过11位标准帧最大ID 0x7FF），跳过该ID";
           continue;
       }

       // --------------------------
       // 4. 逐个添加目标ID到硬件滤波列表
       // --------------------------
       TPCANParameter addFilterParam = static_cast<TPCANParameter>(PCAN_PARAM_FILTER_ADD);
       paramValue = id; // 传入当前要添加的目标ID
       status = CAN_SetValue(m_handle, addFilterParam, &paramValue, sizeof(paramValue));
       if (status != PCAN_ERROR_OK) {
           qWarning() << "添加ID 0x" << QString::number(id, 16).toUpper()
                      << "到滤波列表失败：" << getErrorString(status);
           return false; // 单个ID添加失败则整体返回，避免部分生效
       }
       qInfo() << "已添加滤波ID：0x" << QString::number(id, 16).toUpper();
    }

    qInfo() << "滤波配置完成！仅接收ID：0x3A、0x3B、0x4A";
    return true;
}


void PCANReceiver::startReceiving()
{
    QMutexLocker locker(&m_mutex);
    if (!m_receiveThread.isRunning()) {
        m_running = true;
        m_receiveThread.start();
        qDebug() << "接收线程启动，状态：" << m_receiveThread.isRunning();
    }
}

void PCANReceiver::stopReceiving()
{
    QMutexLocker locker(&m_mutex);
    m_running = false;
    
    if (m_connected) {
        CAN_Uninitialize(m_handle);
        m_connected = false;
        emit connectionStatusChanged(false);
    }
}

void PCANReceiver::receiveLoop()
{
    qInfo() << "receiveLoop()  接收线程进入循环，m_running:" << m_running << "m_connected:" << m_connected;
    TPCANMsg canMsg;
    TPCANStatus status;
    QElapsedTimer timer;
    timer.start();

    while (m_running) {
        // 检查设备连接状态
        if (!m_connected) {
            QThread::msleep(100);
            continue;
        }

        // 关键：读取m_handle时加锁，确保与init中的修改同步
       TPCANHandle currentHandle;
       {
           QMutexLocker locker(&m_mutex); // 局部作用域加锁
           currentHandle = m_handle;
       }
        
        // 读取CAN消息
        status = CAN_Read(currentHandle, &canMsg, nullptr);
        if (status == PCAN_ERROR_OK) {
            qInfo() << "收到原始PCAN消息：ID=0x" << QString::number(canMsg.ID, 16)
                         << "，长度=" << canMsg.LEN
                         << "，数据=" << QByteArray(reinterpret_cast<const char*>(canMsg.DATA), canMsg.LEN).toHex();
            // 处理接收到的消息
            processCanMessage(canMsg);
        }
        else if (status != PCAN_ERROR_QRCVEMPTY) {
            // 发生错误，但不是接收缓冲区为空的错误
            emit errorOccurred("接收数据错误: " + getErrorString(status));
            QThread::msleep(100);
        }
        else {
            // 缓冲区为空，短暂休眠减少CPU占用
            QThread::msleep(1);
        }
        
        // 每100ms检查一次运行状态
        if (timer.elapsed() > 100) {
            timer.restart();
            QMutexLocker locker(&m_mutex);
            if (!m_running) break;
        }
    }
}

void PCANReceiver::processCanMessage(const TPCANMsg& msg)
{
    // 查找对应的消息定义
    const CanMessage* canMessage = m_protManager.findMessage(msg.ID);
    if (!canMessage) {
        qInfo() << "收到未知ID的CAN消息: 0x" << QString::number(msg.ID, 16);
        return;
    }
    
    // 检查数据长度是否匹配
    if (msg.LEN != canMessage->msgLength) {
        qInfo() << "CAN消息" << canMessage->msgName << "长度不匹配，期望:"
                  << canMessage->msgLength << "实际:" << msg.LEN;
        return;
    }
    
    // 转换原始数据为QByteArray
    QByteArray data(reinterpret_cast<const char*>(msg.DATA), msg.LEN);
    
    // 解析每个信号
    for (const CanSignal& signal : canMessage->signalsL) {
        double physValue;
        QString valueDesc;
        
        if (m_protManager.parseSignal(signal, data, physValue, valueDesc)) {
            emit signalReceived(canMessage->msgName, msg.ID, data,
                                signal.signalName, physValue, valueDesc);
        }
    }
}

QString PCANReceiver::getErrorString(TPCANStatus status)
{
    switch (status) {
        case PCAN_ERROR_OK: return "操作成功";
        case PCAN_ERROR_XMTFULL: return "发送队列已满";
        case PCAN_ERROR_QRCVEMPTY: return "接收队列为空";
//        case PCAN_ERROR_BUSERR: return "总线错误";
//        case PCAN_ERROR_ARBLOST: return "仲裁丢失";
        case PCAN_ERROR_BUSOFF: return "总线关闭";
        case PCAN_ERROR_REGTEST: return "寄存器测试失败";
        case PCAN_ERROR_NODRIVER: return "没有驱动程序";
        case PCAN_ERROR_HWINUSE: return "硬件已在使用中";
        default: return QString("未知错误 (0x%1)").arg(status, 0, 16);
    }
}


// 数据发送接口
bool PCANReceiver::sendCanData(quint32 msgId, const QByteArray &data)
{
    QMutexLocker locker(&m_mutex);

    if (!m_connected) {
        emit errorOccurred("发送失败：设备未连接");
        return false;
    }

    // 检查数据长度（CAN 2.0最大8字节）
    if (data.size() > 8) {
        emit errorOccurred("发送失败：数据长度超过8字节");
        return false;
    }

    // 构建PCAN消息结构
    TPCANMsg msg;
    msg.ID = msgId;  // CAN ID
    msg.LEN = data.size();  // 数据长度
    msg.MSGTYPE = PCAN_MESSAGE_STANDARD;  // 标准帧（如需扩展帧可修改）

    // 复制数据到消息缓冲区
    memcpy(msg.DATA, data.constData(), data.size());

    // 发送消息
    TPCANStatus status = CAN_Write(m_handle, &msg);
    qInfo() << "PCANReceiver::sendCanData ID:" << msg.ID << " Data:" << msg.DATA;
    if (status != PCAN_ERROR_OK) {
        emit errorOccurred("发送数据失败: " + getErrorString(status));
        return false;
    }

    return true;
}
